/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package huffman;

import arbre.ArbreHuffman;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.util.HashMap;
import java.util.LinkedHashMap;

/**
 *
 * @author ksz
 */
public class EncoderFichier {

    private String nomFichier;
    private String nomFichierEncode;
    private HashMap bitsCodeDictionnaire;
    private LinkedHashMap dictionnaireFrequences;
    private byte[] tamponLecture;
    private ArbreHuffman arbre;

    public EncoderFichier(String nomFichier, ArbreHuffman arbre, LinkedHashMap dictionnaireFrequences) {
        this.nomFichier = nomFichier;
        this.nomFichierEncode = nomFichier + ".am";
        this.dictionnaireFrequences = dictionnaireFrequences;
        this.arbre = arbre;
        tamponLecture = new byte[256];
        this.bitsCodeDictionnaire = arbre.getBitsCodeDictionnaire();
        construireFichierEncode();
    }

    public void construireFichierEncode() {
        try {

            byte[] tamponEcriture;

            BufferedInputStream entree = new BufferedInputStream(new FileInputStream(nomFichier));


            File fichier = new File(nomFichierEncode);

            if (fichier.exists()) {
                fichier.delete();
            }

            fichier.createNewFile();


            ObjectOutputStream fichierEncode = new ObjectOutputStream(new FileOutputStream(nomFichierEncode));


            fichierEncode.writeObject(dictionnaireFrequences);

            StringBuffer code = new StringBuffer();

            // on va parcourir le fichier à encoder et remplacer chaque caractères
            // par son bit code. On lit 256 octets par 256 octets
            int tailleLu = entree.read(tamponLecture);
            
            while (tailleLu != -1) {


                for (int i = 0; i < tailleLu; i++) {

                    Character cara = Character.valueOf((char) tamponLecture[i]);
                    code.append(bitsCodeDictionnaire.get(cara).toString());

                }

                int nb = (int) (code.length() / 8);

                tamponEcriture = new byte[nb];

                int j, q;

                for (j = 0; j < nb; j++) {

                    StringBuilder codeIntermediaire = new StringBuilder();

                    for (q = 0; q < 8; q++) {
                        codeIntermediaire.append(code.charAt((j * 8) + q));
                    }

                    tamponEcriture[j] = Integer.valueOf(codeIntermediaire.toString(), 2).byteValue();

                }

                fichierEncode.write(tamponEcriture);

                code = new StringBuffer(code.substring(j * 8));

                tailleLu = entree.read(tamponLecture);

            }

            // on complete par des 0 le dernier morceaux pour faire un octet
            if (code.length() < 8) {

                while (code.length() < 8) {
                    code.append("0");
                }

                System.out.println("code fin : " + code.toString());

                int b = Integer.valueOf(code.toString(), 2).byteValue();
                fichierEncode.write(b);

            }


            entree.close();

            fichierEncode.close();

            javax.swing.JOptionPane.showMessageDialog(null, nomFichier + " a été compressé avec succès");

        } catch (FileNotFoundException ex) {
            javax.swing.JOptionPane.showMessageDialog(null, "Le fichier est introuvable");
        } catch (IOException ex) {
            javax.swing.JOptionPane.showMessageDialog(null, "Impossible de lire le fichier");
        }
    }
}
